#include <iostream>
#include <cstring>
#include <stdexcept>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::ostream;
using std::istream;
using std::size_t;
using std::out_of_range;
using std::strlen;
using std::strcpy;
using std::strcmp;
using std::strcat;

class String
{
public:
    // 默认构造函数
    String() : _pstr(new char[1]{'\0'}) {}

    // 从C字符串构造
    String(const char *str) {
        if (str) {
            _pstr = new char[strlen(str) + 1];
            strcpy(_pstr, str);
        } else {
            _pstr = new char[1]{'\0'};
        }
    }

    // 拷贝构造函数
    String(const String &other) : _pstr(new char[strlen(other._pstr) + 1]) {
        strcpy(_pstr, other._pstr);
    }

    // 析构函数
    ~String() {
        delete[] _pstr;
        _pstr = nullptr;
    }

    // 赋值操作符（从另一个String对象）
    String &operator=(const String &other) {
        if (this != &other) {
            delete[] _pstr;
            _pstr = new char[strlen(other._pstr) + 1];
            strcpy(_pstr, other._pstr);
        }
        return *this;
    }

    // 赋值操作符（从C字符串）
    String &operator=(const char *str) {
        //代码复用的思维
        String tmp(str);
        *this = tmp;
        return *this;

#if 0
        delete[] _pstr;
        if (str) {
            _pstr = new char[strlen(str) + 1];
            strcpy(_pstr, str);
        } else {
            _pstr = new char[1]{'\0'};
        }
        return *this;
#endif
    }

    // 拼接操作符（与另一个String对象）
    String &operator+=(const String &other) {
        char *newStr = new char[strlen(_pstr) + strlen(other._pstr) + 1];
        strcpy(newStr, _pstr);
        strcat(newStr, other._pstr);
        delete[] _pstr;
        _pstr = newStr;
        return *this;
    }

    // 拼接操作符（与C字符串）
    String &operator+=(const char *str) {
        String tmp(str);
        *this += tmp;
        return *this;

#if 0
        if (str) {
            char *newStr = new char[strlen(_pstr) + strlen(str) + 1];
            strcpy(newStr, _pstr);
            strcat(newStr, str);
            delete[] _pstr;
            _pstr = newStr;
        }
        return *this;
#endif
    }

    // 下标操作符
    char &operator[](size_t index) {
        if (index >= size()) throw out_of_range("索引超出范围");
        return _pstr[index];
    }

    const char &operator[](size_t index) const {
        if (index >= size()) throw out_of_range("索引超出范围");
        return _pstr[index];
    }

    // 获取字符串长度
    size_t size() const {
        return strlen(_pstr);
    }

    // 获取C字符串表示
    const char* c_str() const {
        return _pstr;
    }

    // 比较操作符
    friend bool operator==(const String &lhs, const String &rhs) {
        return strcmp(lhs._pstr, rhs._pstr) == 0;
    }

    friend bool operator!=(const String &lhs, const String &rhs) {
        return !(lhs == rhs);
    }

    friend bool operator<(const String &lhs, const String &rhs) {
        return strcmp(lhs._pstr, rhs._pstr) < 0;
    }

    friend bool operator>(const String &lhs, const String &rhs) {
        return rhs < lhs;
    }

    friend bool operator<=(const String &lhs, const String &rhs) {
        return !(rhs < lhs);
    }

    friend bool operator>=(const String &lhs, const String &rhs) {
        return !(lhs < rhs);
    }

    friend ostream &operator<<(ostream &os, const String &s);
    friend istream &operator>>(istream &is, String &s);

private:
    char *_pstr;
};

// 流操作符
ostream &operator<<(ostream &os, const String &s) {
    os << s._pstr;
    return os;
}

istream &operator>>(istream &is, String &s) {
    //不知道流中有多少数据
    //char buffer[1024] = {0};
    vector<char> vec;
    vec.reserve(1024);
    char ch = '\0';
    while(is.get(ch), ch !='\n') {
        vec.push_back(ch);
    }
    delete [] s._pstr;
    s._pstr = new char[vec.size() + 1]();
    strncpy(s._pstr, &vec[0], vec.size());
    return is;

    //is >> buffer;
    //s = buffer;
    //return is;
}

// 拼接操作符
String operator+(const String &lhs, const String &rhs) {
    String result(lhs);
    result += rhs;
    return result;
}

String operator+(const String &lhs, const char *rhs) {
    String result(lhs);
    result += rhs;
    return result;
}

String operator+(const char *lhs, const String &rhs) {
    String result(lhs);
    result += rhs;
    return result;
}

// 测试用例
int main() {
    String s1("Hello");
    String s2("World");
    String s3 = s1 + ", " + s2 + "!";
    cout << "拼接后的字符串: " << s3 << endl;

    s3 += " How are you?";
    cout << "使用+=后: " << s3 << endl;

    cin >> s3;

    return 0;
}
